Skip to content

feat: add local personalized trending feed#4234

Open
quantumvoid0 wants to merge 6 commits into
TeamPiped:masterfrom
quantumvoid0:feat/personalized-trending
Open

feat: add local personalized trending feed#4234
quantumvoid0 wants to merge 6 commits into
TeamPiped:masterfrom
quantumvoid0:feat/personalized-trending

Conversation

@quantumvoid0
Copy link
Copy Markdown

@quantumvoid0 quantumvoid0 commented May 9, 2026

This PR includes a new feature for the piped:trending page which allows users to enable a more personalized trending section from watch history.

It reads watch history from IndexedDB, ranks channels by watch count, fetches recent 5 videos from top 10 channels, Also added getPreferenceBoolean import. This feature can be turned on/off from preferences and also have the ability to show just the personalized section without global trending.

P.S:
Variables that are never reassigned should be const. so changed let->const... No functional difference, just cleaner code.

added RSS guard, without it, the RSS link would render with a URL like /feed/unauthenticated/rss?channels= (empty channels string) when not logged in and no subscriptions exist. Clicking it would hit the API with an empty parameter, likely returning an error or garbage. The null return + v-if just hides the button entirely in that case rather than showing a broken link.

Summary by CodeRabbit

  • New Features

    • Personalized trending on the Trending page using your watch history.
    • Two new preference toggles: enable personalized trending and optionally show only personalized recommendations (visible when watch history is enabled).
    • New localized labels and a “no watch history” message for personalized trending.
  • Bug Fixes

    • RSS/feed icon now only appears when an RSS link is available.
    • Improved list update behavior to prevent inconsistent video lists.

Review Change Stack

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 9, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds personalized trending using watch-history (IndexedDB) with two new preference toggles and translations; fetches per-channel recommendations, deduplicates and interleaves or filters results; plus minor FeedPage null-safety and strict-equality fixes.

Changes

Personalized Trending Feature

Layer / File(s) Summary
Data / Preferences & Localization
src/components/PreferencesPage.vue, src/locales/en.json
Adds personalizedTrending and personalizedTrendingOnly boolean preferences (default false) and three localization entries (actions.personalized_trending, actions.personalized_trending_only, info.no_watch_history_trending).
TrendingPage Core Implementation
src/components/TrendingPage.vue
Adds IndexedDB cursor helper and getPreferredChannels(); introduces fetchChannelVideos() with in-memory TTL cache and interleave(); replaces fetchTrending() with preference-driven logic that fetches base trending, optionally fetches preferred-channel streams, deduplicates by video id, and returns filtered or interleaved results; template uses a loaded flag and mount/activation logic now refreshes when personalization is enabled.
PreferencesPage UI Integration
src/components/PreferencesPage.vue
Inserts conditional PreferenceRow / PreferenceSwitch controls for personalizedTrending (when watchHistory) and nested personalizedTrendingOnly (when both watchHistory and personalizedTrending).

FeedPage Code Quality

Layer / File(s) Summary
FeedPage Improvements
src/components/FeedPage.vue
Wraps RSS <a> with v-if="getRssUrl"; getRssUrl returns null when unauthenticated channels are missing instead of constructing a URL; uses strict inequality (!==) in loadMoreVideos() length comparison.

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant TrendingComponent
  participant IndexedDB
  participant Network
  participant Cache
  User->>TrendingComponent: open Trending page
  TrendingComponent->>IndexedDB: read watch_history (getPreferredChannels)
  TrendingComponent->>Network: fetch base trending
  TrendingComponent->>Cache: request per-channel fetch
  Cache->>Network: fetch per-channel streams (on cache miss)
  Network-->>TrendingComponent: return results
  TrendingComponent->>TrendingComponent: dedupe / interleave / filter
  TrendingComponent-->>User: render videos
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 I hop through watch history to find a friend,

weaving recommended streams into the trending blend.
Toggles hum softly, labels now in place,
RSS link guarded — tidy, safe, and chaste.
Code hops along — a gentle, spry embrace.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The pull request title accurately summarizes the main change: adding a local personalized trending feed feature.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (2)
src/components/FeedPage.vue (1)

98-102: 💤 Low value

Consider removing the unnecessary else block.

Since the if block on line 97 returns early, the else is redundant. The code would be cleaner without it:

♻️ Optional refactor to remove redundant else
 const getRssUrl = computed(() => {
     if (isAuthenticated()) return authApiUrl() + "/feed/rss?authToken=" + getAuthToken();
-    else {
-        const channels = getUnauthenticatedChannels();
-        if (!channels) return null;
-        return authApiUrl() + "/feed/unauthenticated/rss?channels=" + channels;
-    }
+    const channels = getUnauthenticatedChannels();
+    if (!channels) return null;
+    return authApiUrl() + "/feed/unauthenticated/rss?channels=" + channels;
 });
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/FeedPage.vue` around lines 98 - 102, The else after the early
return is redundant; remove the else block and dedent its body so that when the
earlier condition returns, execution continues to call
getUnauthenticatedChannels(), check for null, and return authApiUrl() +
"/feed/unauthenticated/rss?channels=" + channels; update the branch around
getUnauthenticatedChannels() and authApiUrl() in FeedPage.vue (the block
containing getUnauthenticatedChannels and the return) accordingly to preserve
behavior but eliminate the unnecessary else.
src/components/TrendingPage.vue (1)

72-83: 💤 Low value

Simplify interleave with a loop instead of three repeated pushes.

The repeated if (ti < trending.length) out.push(trending[ti++]); block makes the 3:1 ratio implicit. A small loop expresses the intent and makes the ratio trivially tunable.

♻️ Suggested refactor
 function interleave(trending, recommended) {
     const out = [];
     let ti = 0,
         ri = 0;
+    const trendingPerRecommended = 3;
     while (ti < trending.length || ri < recommended.length) {
-        if (ti < trending.length) out.push(trending[ti++]);
-        if (ti < trending.length) out.push(trending[ti++]);
-        if (ti < trending.length) out.push(trending[ti++]);
+        for (let i = 0; i < trendingPerRecommended && ti < trending.length; i++) {
+            out.push(trending[ti++]);
+        }
         if (ri < recommended.length) out.push(recommended[ri++]);
     }
     return out;
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/TrendingPage.vue` around lines 72 - 83, The interleave
function currently repeats three identical checks to push trending items;
replace those three lines with a small inner loop so the 3:1 ratio is explicit
and tunable. In function interleave(trending, recommended) (variables out, ti,
ri), inside the while loop run a for-loop that iterates up to 3 times (or until
ti >= trending.length) and pushes trending[ti++] each iteration, then keep the
single conditional push for recommended[ri++]; this makes the ratio configurable
and removes the repeated if statements.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/components/TrendingPage.vue`:
- Around line 102-113: The dedup logic in dedup currently extracts the video id
via split("v=")[1], which leaves trailing query params and breaks deduping;
change the extraction to parse the v query parameter properly (e.g., use
URL/URLSearchParams or parse the querystring) inside dedup so you get
searchParams.get('v') for each v.url, handle relative URLs by supplying a base
or parsing only the query portion, and keep the same seen Set/return behavior
used by dedup; update references to dedup, seen, interleave,
personalizedTrendingOnly, recommended, and trending accordingly.
- Around line 65-70: fetchChannelVideos currently slices the first 5
relatedStreams without guaranteeing order and re-fetches channel data on every
page load; update fetchChannelVideos to first sort each r.value.relatedStreams
by uploadedDate (newest first) before taking slice(0,5), and implement a
short-lived cache (e.g., store the combined per-channel results keyed by
channelIds in sessionStorage or an in-memory Map with a 5–10 minute TTL) so the
Promise.allSettled call is skipped when cached data is fresh; keep references to
relatedStreams, uploadedDate, and fetchChannelVideos to locate where to add
sorting and cache-check logic.
- Around line 45-63: In getPreferredChannels, guard against empty channel IDs
produced when video.uploaderUrl has trailing slashes by normalizing/extracting
the id and skipping falsy/empty results before incrementing counts; specifically
update the id extraction (from video.uploaderUrl.split("/").pop()) to trim
trailing slashes or otherwise derive a non-empty id and only call counts.set(id,
...) when id is truthy so empty strings can't be counted among preferred
channels.

In `@src/locales/en.json`:
- Around line 136-137: Lines defining the keys "personalized_trending" and
"personalized_trending_only" use tab indentation instead of the project's
4-space JSON indentation; replace any tab characters before those entries with 4
spaces so their indentation matches the rest of src/locales/en.json, then run
the repo formatter (Prettier/EditorConfig) to normalize spacing and remove the
noisy diff.

---

Nitpick comments:
In `@src/components/FeedPage.vue`:
- Around line 98-102: The else after the early return is redundant; remove the
else block and dedent its body so that when the earlier condition returns,
execution continues to call getUnauthenticatedChannels(), check for null, and
return authApiUrl() + "/feed/unauthenticated/rss?channels=" + channels; update
the branch around getUnauthenticatedChannels() and authApiUrl() in FeedPage.vue
(the block containing getUnauthenticatedChannels and the return) accordingly to
preserve behavior but eliminate the unnecessary else.

In `@src/components/TrendingPage.vue`:
- Around line 72-83: The interleave function currently repeats three identical
checks to push trending items; replace those three lines with a small inner loop
so the 3:1 ratio is explicit and tunable. In function interleave(trending,
recommended) (variables out, ti, ri), inside the while loop run a for-loop that
iterates up to 3 times (or until ti >= trending.length) and pushes
trending[ti++] each iteration, then keep the single conditional push for
recommended[ri++]; this makes the ratio configurable and removes the repeated if
statements.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: e3bae360-fe99-4f14-965a-1a2a15276d2f

📥 Commits

Reviewing files that changed from the base of the PR and between da7ab35 and 9d7d555.

📒 Files selected for processing (4)
  • src/components/FeedPage.vue
  • src/components/PreferencesPage.vue
  • src/components/TrendingPage.vue
  • src/locales/en.json

Comment thread src/components/TrendingPage.vue
Comment thread src/components/TrendingPage.vue Outdated
Comment thread src/components/TrendingPage.vue Outdated
Comment thread src/locales/en.json Outdated
Wasnt able to see this bcz vim had formatted the file cleanly
@quantumvoid0
Copy link
Copy Markdown
Author

I see there are some issues in the code as reported by coderabbit...ill see to fixing it first

@quantumvoid0 quantumvoid0 marked this pull request as draft May 9, 2026 11:44
@quantumvoid0 quantumvoid0 marked this pull request as ready for review May 10, 2026 04:21
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/components/TrendingPage.vue (1)

144-174: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Prevent duplicate API requests on first mount when personalizedTrending is enabled.

With the route wrapped in <keep-alive> (confirmed in App.vue), onActivated fires immediately after onMounted on initial load. When personalizedTrending is enabled, both lifecycle hooks call fetchTrending(region), resulting in duplicate API requests: 1 extra /trending call and up to 10 extra /channel/{id} requests during cold load. The onActivated hook also clears channelCache, forcing all channel data to be refetched unnecessarily.

Add a first-mount guard to skip the onActivated refetch on initial mount:

♻️ Proposed guard
+const hasMounted = ref(false);
+
 onMounted(() => {
     if (route.path == import.meta.env.BASE_URL && getPreferenceString("homepage", "trending") == "feed") {
         return;
     }
     const region = getPreferenceString("region", "US");
     fetchTrending(region).then(vids => {
         videos.value = vids;
         loaded.value = true;
         updateWatched(videos.value);
         fetchDeArrowContent(videos.value);
+        hasMounted.value = true;
     });
 });

 onActivated(() => {
     document.title = t("titles.trending") + " - Piped";
     if (videos.value.length > 0) updateWatched(videos.value);
     if (route.path == import.meta.env.BASE_URL) {
         const homepage = getHomePage();
         if (homepage !== undefined) router.push(homepage);
     }
-    if (getPreferenceBoolean("personalizedTrending", false)) {
+    if (hasMounted.value && getPreferenceBoolean("personalizedTrending", false)) {
         channelCache.clear();
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/TrendingPage.vue` around lines 144 - 174, The onMounted and
onActivated hooks both call fetchTrending (and clear channelCache) when
personalizedTrending is enabled, causing duplicate requests on initial mount;
add a first-activation guard: declare a local ref/boolean (e.g., firstActivation
= ref(true)) near the component setup, in onActivated check if firstActivation
is true then set it to false and skip the personalizedTrending branch (do not
clear channelCache or call fetchTrending), and ensure onMounted sets
firstActivation to false after its initial work so subsequent activations run
the existing personalizedTrending logic; reference symbols: onMounted,
onActivated, personalizedTrending, channelCache, fetchTrending, videos, loaded.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/components/TrendingPage.vue`:
- Around line 164-173: The personalized-refetch branch (guarded by
getPreferenceBoolean("personalizedTrending", false)) replaces videos.value but
doesn't call updateWatched, so watched badges aren't reapplied; update the .then
handler on fetchTrending (the block that sets videos.value, toggles
loaded.value, and calls fetchDeArrowContent(videos.value)) to also call
updateWatched(videos.value) after the new videos are set (e.g., call
updateWatched(videos.value) following fetchDeArrowContent) so watched state is
reapplied for the refreshed list.
- Around line 8-12: The empty-state paragraph currently shows whenever
videos.length === 0; change its guard to only render the "no watch history" copy
for the personalized-only path by adding the personalized flag (e.g.
personalizedOnly or personalizedTrending) and ensuring loaded is true before
showing it (so the message is not shown during loading or for non-personalized
empty results). Update the v-if on the paragraph to require videos.length === 0
&& loaded && personalizedOnly (or the appropriate personalizedTrending variable
exported from the <script setup>), and leave a generic/alternative empty-state
message for the non-personalized case.
- Around line 92-95: The sort currently compares the human-readable uploadedDate
strings on r.value.relatedStreams which yields lexicographic ordering; change
the comparator to use the numeric uploaded timestamp (e.g., b.uploaded ?? 0 and
a.uploaded ?? 0) so streams are sorted by most-recent uploaded ms. Locate the
sort call on r.value.relatedStreams, replace the (a, b) => ((b.uploadedDate ??
0) > (a.uploadedDate ?? 0) ? 1 : -1) comparator with one that subtracts the
numeric uploaded values (or otherwise compares b.uploaded and a.uploaded) and
keep the .slice(0, 5) limiting afterwards.

---

Outside diff comments:
In `@src/components/TrendingPage.vue`:
- Around line 144-174: The onMounted and onActivated hooks both call
fetchTrending (and clear channelCache) when personalizedTrending is enabled,
causing duplicate requests on initial mount; add a first-activation guard:
declare a local ref/boolean (e.g., firstActivation = ref(true)) near the
component setup, in onActivated check if firstActivation is true then set it to
false and skip the personalizedTrending branch (do not clear channelCache or
call fetchTrending), and ensure onMounted sets firstActivation to false after
its initial work so subsequent activations run the existing personalizedTrending
logic; reference symbols: onMounted, onActivated, personalizedTrending,
channelCache, fetchTrending, videos, loaded.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: cfddc4f1-d567-46f0-a691-ebf8b050c9b1

📥 Commits

Reviewing files that changed from the base of the PR and between df5b3a7 and 15c71d6.

📒 Files selected for processing (2)
  • src/components/TrendingPage.vue
  • src/locales/en.json
✅ Files skipped from review due to trivial changes (1)
  • src/locales/en.json

Comment thread src/components/TrendingPage.vue
Comment thread src/components/TrendingPage.vue
Comment thread src/components/TrendingPage.vue
@quantumvoid0 quantumvoid0 marked this pull request as draft May 10, 2026 05:00
@quantumvoid0 quantumvoid0 marked this pull request as ready for review May 10, 2026 05:15
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (1)
src/components/TrendingPage.vue (1)

8-10: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Derive the empty-state flag from the effective personalized mode.

personalizedOnly.value currently mirrors only the secondary toggle. If personalizedTrending is off but personalizedTrendingOnly is still stored as true, an empty plain /trending response will still show the watch-history message.

Suggested fix
-    personalizedOnly.value = getPreferenceBoolean("personalizedTrendingOnly", false);
+    personalizedOnly.value =
+        getPreferenceBoolean("personalizedTrending", false) &&
+        getPreferenceBoolean("personalizedTrendingOnly", false);
...
-        personalizedOnly.value = getPreferenceBoolean("personalizedTrendingOnly", false);
+        personalizedOnly.value =
+            getPreferenceBoolean("personalizedTrending", false) &&
+            getPreferenceBoolean("personalizedTrendingOnly", false);

Also applies to: 151-175

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/TrendingPage.vue` around lines 8 - 10, personalizedOnly
currently mirrors only the secondary toggle and can be true even when
personalized trending is disabled; change personalizedOnly to be derived from
the effective personalized mode (i.e., require both the main
personalizedTrending flag and the secondary personalizedTrendingOnly flag) so it
only becomes true when personalizedTrending is enabled AND
personalizedTrendingOnly is set; update the places referencing personalizedOnly
(the empty-state v-if at the top and the other usage around the 151-175 block)
to use this computed/derived value instead of directly mirroring
personalizedTrendingOnly.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/components/TrendingPage.vue`:
- Around line 114-144: fetchTrending currently allows failures from
getPreferredChannels() or fetchChannelVideos to bubble up and prevent the
non-personalized trending fallback; wrap the personalized-path async calls (the
Promise.all that invokes getPreferredChannels() and the subsequent
fetchChannelVideos call) in a try/catch so that on any error you fall back to
returning the plain fetchJson(apiUrl() + "/trending", { region: region || "US"
}) result; ensure you still honor personalizedTrendingOnly (i.e., if
personalizedTrendingOnly is true and an error occurs, return the plain trending)
and keep using dedup/interleave as before when the personalized calls succeed.

---

Duplicate comments:
In `@src/components/TrendingPage.vue`:
- Around line 8-10: personalizedOnly currently mirrors only the secondary toggle
and can be true even when personalized trending is disabled; change
personalizedOnly to be derived from the effective personalized mode (i.e.,
require both the main personalizedTrending flag and the secondary
personalizedTrendingOnly flag) so it only becomes true when personalizedTrending
is enabled AND personalizedTrendingOnly is set; update the places referencing
personalizedOnly (the empty-state v-if at the top and the other usage around the
151-175 block) to use this computed/derived value instead of directly mirroring
personalizedTrendingOnly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 3a4a3a20-df9e-4885-a0ba-d8c944f17f17

📥 Commits

Reviewing files that changed from the base of the PR and between 15c71d6 and ee55e97.

📒 Files selected for processing (1)
  • src/components/TrendingPage.vue

Comment thread src/components/TrendingPage.vue
@quantumvoid0 quantumvoid0 marked this pull request as draft May 10, 2026 05:21
@quantumvoid0 quantumvoid0 marked this pull request as ready for review May 10, 2026 09:17
const cached = channelCache.get(cacheKey);
if (cached && Date.now() - cached.ts < CHANNEL_CACHE_TTL) return cached.data;

const results = await Promise.allSettled(channelIds.map(id => fetchJson(apiUrl() + "/channel/" + id)));
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you use the unauthenticated channel feeds api, since this is quite expensive on the server? You can pass multiple channel IDs to it too.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

surely, ill implement the fix..but there seems to be another issue preventing the code in this PR from running, about a week ago i noticed that videos section in channels no longer load, and this affected the trending page too as it reads from there, i dont think its just my side, bcz the piped.video server also had the same issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants